package com.atguigu.tingshu.album.task;

import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@Slf4j
public class RebuildBulooTask {

    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private AlbumInfoService albumInfoService;
    @Scheduled(cron = "0 0 2 1 * ?")
    //@Scheduled(cron = "0/5 * * * * ?")
    public void rebuildBloomFilter(){
        //1.获取现有布隆过滤器对象，得到配置信息：1.期望数据规模  2.误判率 3.现有元素数量(预估值)
        RBloomFilter<Long> oldbloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
        long expectedInsertions = oldbloomFilter.getExpectedInsertions();
        double falseProbability = oldbloomFilter.getFalseProbability();
        long count = oldbloomFilter.count();
        //2.判断是否满足扩容条件：现有元素数量大于等于期望数据规模
        if (expectedInsertions >= count){
            log.info("满足扩容的条件开始扩容====================");
            //2.1 先初始化布隆过滤器 原有期望数据规模*2
            RBloomFilter<Long> newbloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER + "new");
            if (!newbloomFilter.isExists()){
                newbloomFilter.tryInit(expectedInsertions*2,falseProbability);
                //2.2 将数据中合法的id加入到布隆过滤器中
                List<AlbumInfo> list = albumInfoService.list(new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getStatus, SystemConstant.ALBUM_STATUS_PASS)
                        .select(AlbumInfo::getId));
                for (AlbumInfo albumInfo : list) {
                    newbloomFilter.add(albumInfo.getId());
                }
                //2.3 删除旧的布隆过滤器
                oldbloomFilter.delete();
                //2.4 重命名过滤器 设置为原来的名字
                newbloomFilter.rename(RedisConstant.ALBUM_BLOOM_FILTER);
            }else {
                //开始重建布隆过滤器
                log.info("不满足扩容的条件,重建布隆过滤器");
                RBloomFilter<Long> newBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER+"new");
                //初始化布隆过滤器
                newBloomFilter.tryInit(expectedInsertions,falseProbability);
                //将现有的合法id加入布隆过滤期中
                List<AlbumInfo> list = albumInfoService.list(new LambdaQueryWrapper<AlbumInfo>()
                        .eq(AlbumInfo::getStatus, SystemConstant.ALBUM_STATUS_PASS)
                        .select(AlbumInfo::getId)
                );
                for (AlbumInfo albumInfo : list) {
                    newBloomFilter.add(albumInfo.getId());
                }
                //删除旧的布隆过滤器
                oldbloomFilter.delete();
                //将新的过滤器 改名为旧名
                newBloomFilter.rename(RedisConstant.ALBUM_BLOOM_FILTER);
                log.info("重构过滤器完成");
            }
        }


    }
}
